package org.dreamwork.tools.code.analyzer.jfx;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.ButtonBar;
import javafx.scene.control.ButtonType;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import org.dreamwork.concurrent.Looper;
import org.dreamwork.injection.IObjectContext;
import org.dreamwork.injection.ObjectContextFactory;
import org.dreamwork.tools.code.analyzer.ContextMain;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Optional;

public class JFXMain extends Application {
    private Image icon = null;

    public static void main (String[] args) {
        launch (args);
    }

    @Override
    public void start (Stage stage) {
        final ClassLoader loader = getClass ().getClassLoader ();
        try (InputStream in = loader.getResourceAsStream ("images/cover.png")) {
            if (in != null) {
                Image image = new Image (in);
                ImageView view = new ImageView (image);
                Pane pane = new Pane ();
                pane.getChildren ().add (view);
                Scene scene = new Scene (pane, 627, 417);
                stage.setScene (scene);
            } else {
                System.err.println ("image not found");
            }
        } catch (IOException ex) {
            ex.printStackTrace ();
        }

        try (InputStream in = loader.getResourceAsStream ("images/code-2.png")) {
            if (in != null) {
                icon = new Image (in);
                stage.getIcons ().add (icon);
            } else {
                System.err.println ("icon not found");
            }
        } catch (IOException ex) {
            ex.printStackTrace ();
        }
        Platform.setImplicitExit (false);
        stage.initStyle (StageStyle.UNDECORATED);
        stage.show ();

        String[] args = getParameters ().getRaw().toArray(new String[0]);

        Looper.invokeLater (() -> {
            try {
                IObjectContext context = ObjectContextFactory.start (ContextMain.class, args);
                if (icon != null) {
                    context.register ("icon", icon);
                }
                Platform.runLater (() -> {
                    try {
                        showMainStage (loader, context, stage);
                    } catch (IOException ex) {
                        ex.printStackTrace ();
                        System.exit (-1);
                    }
                });
            } catch (Exception ex) {
                ex.printStackTrace ();
                System.exit (-1);
            }
        });
    }

    private void showMainStage (ClassLoader loader, IObjectContext context, Stage root) throws IOException {
        URL url = loader.getResource ("jfx/main.fxml");
        if (url != null) {
            Stage main = new Stage ();
            main.setTitle ("Code Analyzer ");
            main.setMinWidth (1080);

            FXMLLoader fxml = new FXMLLoader (url);
            Parent parent = fxml.load ();
            MainController controller = fxml.getController ();
            controller.setOwner (main);
            controller.setContext (context);

            Scene scene = new Scene (parent);
            main.setScene (scene);
            main.setOnShown (event -> root.hide ());
            main.setOnCloseRequest (event -> {
                ButtonBar.ButtonData data = confirmExit (main);
                switch (data) {
                    case YES:
                        new Thread (()->{
                            try {
                                context.dispose ();
                            } catch (Throwable ignore) {}
                            Platform.exit ();
                            System.exit (0);
                        }).start ();
                        break;
                    case NO:
                        event.consume ();
                        break;
                }
            });
            if (icon != null) {
                main.getIcons ().add (icon);
            }
            main.show ();
        } else {
            System.err.println ("main.fxml not found.");
        }
    }

    private ButtonBar.ButtonData confirmExit (Stage owner) {
        Optional<ButtonType> optional = DialogHelp.option (owner, "Are you sure to quit?", ButtonType.YES, ButtonType.NO);
        ButtonType type = optional.orElse (ButtonType.NO);
        return type.getButtonData ();
    }
}